package com.yx.changdao.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yx.changdao.common.entity.SysPermission;
import com.yx.changdao.common.entity.SysRole;
import com.yx.changdao.common.entity.SysUser;
import com.yx.changdao.common.entity.SysUserRole;
import com.yx.changdao.common.exception.AlertException;
import com.yx.changdao.common.mapper.SysUserRoleMapper;
import com.yx.changdao.common.utils.SysConst;
import com.yx.changdao.service.SysRolePermissionService;
import com.yx.changdao.service.SysRoleService;
import com.yx.changdao.service.SysUserRoleService;
import com.yx.changdao.service.SysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

/**
 * @Title: SysUserRoleServiceImpl
 * @Description: 系统用户角色服务实现。
 * @Auther: Zhangjiashun
 * @Version: 1.0
 * @create 2019/11/6 12:16
 */
@Service
public class SysUserRoleServiceImpl extends ServiceImpl<SysUserRoleMapper, SysUserRole> implements SysUserRoleService {

    @Autowired
    private SysRolePermissionService sysRolePermissionService;

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;


    /**
     * 添加用户角色
     *
     * @param user 用户
     * @param role 角色
     * @return 用户角色
     */
    @Override
    public SysUserRole addUserRole(SysUser user, SysRole role) throws AlertException {
        return this.addUserRole(user.getUserId(), role.getRoleId());
    }

    /**
     * 添加用户角色
     *
     * @param userId 用户id
     * @param roleId 角色id
     * @return 用户角色
     */
    @Override
    public SysUserRole addUserRole(String userId, String roleId) throws AlertException {
        SysUser userById = this.sysUserService.getUserById(userId);
        if (userById == null) {
            throw new AlertException("不存在的userId");
        }
        SysRole role = this.sysRoleService.getRole(roleId);
        if (role == null) {
            throw new AlertException("不存在的roleId");
        }
        SysUserRole sysUserRole = new SysUserRole();
        sysUserRole.setRoleId(roleId);
        sysUserRole.setUserId(userId);

        return this.save(sysUserRole) ? sysUserRole : null;
    }

    /**
     * 获取用户角色列表
     *
     * @param userId 用户id
     * @return 角色列表
     */
    @Override
    public List<SysRole> getUserRoles(String userId) {
        List<SysUserRole> sysUserRoleList = this.getSysUserRoles(userId);
        List<String> roles_id = new ArrayList<>();
        for (SysUserRole sysUserRole : sysUserRoleList) {
            roles_id.add(sysUserRole.getRoleId());
        }

        return this.getRolesByRoleIds(roles_id);
    }

    /**
     * 获取用户角色列表
     *
     * @param userId 用户id
     * @return 角色id列表
     */
    @Override
    public List<String> getUserRoleIds(String userId) {
        List<SysRole> userRoles = this.getUserRoles(userId);
        List<String> roles = new ArrayList<>();
        userRoles.forEach(role -> roles.add(role.getRoleId()));
        return roles;
    }

    /**
     * 获取用户权限列表
     *
     * @param userId 用户id
     * @return 用户拥有的权限id列表
     */
    @Override
    public List<String> getUserPermissionIds(String userId) {
        List<SysPermission> userPermissions = this.getUserPermissions(userId);
        List<String> permissions = new ArrayList<>();
        userPermissions.forEach(permission -> permissions.add(permission.getPermId()));
        return permissions;
    }

    /**
     * 获取用户权限列表
     *
     * @param userId 用户id
     * @return 用户拥有的权限列表
     */
    @Override
    public List<SysPermission> getUserPermissions(String userId) {
        List<SysPermission> permissions = new ArrayList<>();
        List<SysUserRole> sysUserRoleList = this.getSysUserRoles(userId);
        for (SysUserRole sysUserRole : sysUserRoleList) {
            // 如果用户角色中含有管理员角色 添加所有权限。
            if (sysUserRole.getRoleId().equals(SysConst.SYS_ROLE)) {
                permissions.addAll(this.sysRolePermissionService.getAllPermissions());
            } else {
                List<SysPermission> rolePermissions = this.sysRolePermissionService.getRolePermissions(sysUserRole.getRoleId());
                permissions.addAll(rolePermissions);
            }
        }

        return permissions;
    }

    /**
     * 删除用户权限
     *
     * @param userId 用户id
     * @param roleId 角色id
     * @return 是否删除成功
     */
    @Override
    public Boolean delUserPermission(String userId, String roleId) {
        return this.remove(new QueryWrapper<SysUserRole>().lambda()
                .eq(SysUserRole::getUserId, userId)
                .eq(SysUserRole::getRoleId, roleId));
    }

    /**
     * 删除用户权限
     *
     * @param userRole 用户角色
     * @return 是否删除成功
     */
    @Override
    public Boolean delUserPermission(SysUserRole userRole) {
        return this.delUserPermission(userRole.getUserId(), userRole.getRoleId());
    }

    /**
     * 删除用户权限
     *
     * @param user 用户
     * @return 是否删除成功
     */
    @Override
    public Boolean delUserAllPermission(SysUser user) {
        return this.delUserAllPermission(user.getUserId());
    }

    /**
     * 删除用户所有权限
     *
     * @param userId 用户id
     * @return 是否删除成功
     */
    @Override
    public Boolean delUserAllPermission(String userId) {
        return this.remove(new QueryWrapper<SysUserRole>().lambda()
                .eq(SysUserRole::getUserId, userId));
    }


    /**
     * 获取用户角色
     *
     * @param userId 用户id
     * @return 用户的角色列表
     */
    private List<SysUserRole> getSysUserRoles(String userId) {
        return this.list(new QueryWrapper<SysUserRole>().lambda()
                .eq(SysUserRole::getUserId, userId));
    }


    /**
     * 根据角色id列表 获取角色列表
     *
     * @param roleIds 角色id
     * @return 角色列表
     */
    private List<SysRole> getRolesByRoleIds(List<String> roleIds) {
        List<SysRole> roles = new ArrayList<>();
        for (String roleId : roleIds) {
            SysRole r = this.sysRolePermissionService.getRole(roleId);
            if (null != r) {
                roles.add(r);
            }
        }
        return roles;
    }
}
